{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "11be9f00",
   "metadata": {},
   "source": [
    "### SOLID原则\n",
    "1. SRP:单一职责原则\n",
    "2. OCP:开放-关闭原则\n",
    "3. LSP:里氏替换原则\n",
    "4. ISP：接口隔离原则\n",
    "5. DIP:依赖倒置原则"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8b683347",
   "metadata": {},
   "source": [
    "## 10.1 类型注解基础"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "3aa8fccf",
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "\n",
    "class Duck:\n",
    "    def __init__(self, color: str):\n",
    "        self.color = color\n",
    "    \n",
    "    def quack(self) -> None:\n",
    "        print(\"Hi, I'm a {self.color} duck!\")\n",
    "\n",
    "def create_random_ducks(number: int) -> List[Duck]:\n",
    "    ducks: List[Duck] = []\n",
    "    for _ in number:\n",
    "        color = random.choice(['yellow', 'white', 'gray'])\n",
    "        ducks.append(Duck(color = color))\n",
    "    return ducks"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cdb5a01d",
   "metadata": {},
   "source": [
    "## 10.2 SRP: 单一职责原则\n",
    "- 一个类应该仅有一个被修改的理由\n",
    "- 大类拆小类\n",
    "## 10.3 OCP:开放-关闭原则\n",
    "- 类应该对外扩展开放，对修改封闭\n",
    "- 通过分析需求，找到代码易变的部分，是让类符合OCP的关键\n",
    "- 使用子类继承的方法让类符合OCP\n",
    "- 通过算法类与依赖注入，可以让类符合OCP\n",
    "- 将数据与逻辑分离，使用数据驱动的方式也是实现OCP的好办法\n",
    "## 10.4 LSP:里氏替换原则\n",
    "- LSP认为子类应该可以任意替代父类使用\n",
    "- 子类不应该抛出父类不认识的异常\n",
    "- 子类方法应该返回与父类一致的类型，或则返回父类返回值的子类型对象\n",
    "- 子类的方法参数应该和父类父类方法完全一致，或者要求更为宽松\n",
    "- 某些类可能会存在隐式合约，违反这些合约也会导致违反LSP\n",
    "## 10.4 DIP:依赖倒置原则\n",
    "- DIP认为高层模块和底层模块都应该依赖于抽象\n",
    "- 编写单元测试有一个原则：测试行为，而不是测试实现\n",
    "- 单元测试不宜使用太多mock，否则需要调整设计\n",
    "- 依赖抽象的好处是，修改底层模块实现不会影响高层代码\n",
    "- 在Python中，你可以用abc模块来定义抽象类\n",
    "- 除abc以外，你也可以用Protocol等技术来完成依赖倒置\n",
    "## 10.5 ISP\n",
    "- ISP认为客户依赖的接口不应该包含任何它不需要的方法\n",
    "- 设计接口就是设计抽象\n",
    "- 写更小的类，更小的接口在大多数情况下是个好主意"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "base",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.13.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
